﻿#include <iostream>

using namespace std;

//class Person
//{
//public:
//	void Print()
//	{
//		cout << _age << endl;
//	}
//protected:
//	string _name = "张三"; // 姓名
//private:
//	int _age = 18; // 年龄
//};
// 
//class Student : public Person  //公有继承
//{
//public:
//	void func()
//	{
//		// 基类的private成员，派生类中不可见
//		//cout << _age << endl;
//		//基类的protected成员可见
//		cout << _name << endl;
//		Print(); //基类的public成员
//	}
//protected:
//	int _stunum = 1; // 学号
//};


//class Person
//{
//public:
//	// 进入校园/图书馆/实验室刷⼆维码等⾝份认证
//	void identity()
//	{
//		cout << "void identity()" << _name << endl;
//	}
//protected:
//	string _name = "张三"; // 姓名
//	string _address; // 地址
//	string _tel; // 电话
//	int _age = 18; // 年龄
//};

//class Student : public Person
//{
//public:
//	// 学习
//	void study()
//	{
//		// ...
//	}
//protected:
//	int _stuid = 1234567; // 学号
//};
//
//class Teacher : public Person
//{
//public:
//	// 授课
//	void teaching()
//	{
//		//...
//	}
//protected:
//	string title; // 职称
//};

//int main()
//{
//	Student s;
//	//s.func();
//	//s.Print();
//	//s._name;
//
//	return 0;
//}


//切片
//class Person
//{
//protected:
//	string _name = "张三"; // 姓名
//private:
//	int _age = 18; // 年龄
//};
//	 
//class Student : public Person  
//{
//protected:
//	int _stunum = 1; // 学号
//};
//
//int main()
//{
//	Student stu;
//	// 1.派⽣类对象可以赋值给基类的指针/引⽤
//	Person* ptr = &stu;
//	Person& ref = stu;
//	// 生类对象可以赋值给基类的对象，通过调用基类的拷贝构造完成
//	Person per = stu;
//	// 2.基类对象不能赋值给派生类对象，这里会编译报错
//	//stu = per;
//
//	return 0;
//}

//隐藏
//class Person
//{
//protected:
//	string _name = "张三"; // 姓名
//	int _id = 1111;
//};
//
//class Student : public Person
//{
//public:
//	void func()
//	{
//		//基类Person的_id与派生类Studentd的_id构成隐藏
//		cout << "Person _id:" << Person::_id << endl;
//		cout << "Student _id:" << _id << endl;
//	}
//protected:
//	int _stunum = 1; // 学号
//	int _id = 2222;
//};


//class A
//{
//public:
//	void fun()
//	{ cout << "func()" << endl; }
//};
//class B : public A
//{
//public:
//	void fun(int i)
//	{ cout << "func(int i)" << i << endl; }	
//};
//int main()
//{
//	B b;
//	b.fun(10);
//	b.fun();
//	return 0;
//};


//默认成员函数
class Person
{
public:
	//Person(const char* name = "peter")
	Person(const char* name)
		: _name(name)
	{
			cout << "Person()" << endl;
	}

	Person(const Person& p)
		: _name(p._name)
	{
		cout << "Person(const Person& p)" << endl;
	}

	Person& operator=(const Person& p)
	{
		cout << "Person operator=(const Person& p)" << endl;
		if (this != &p)
			_name = p._name;
		return *this;
	}

	~Person()
	{
		cout << "~Person()" << endl;
	}
protected:
	string _name; // 姓名
};

// 把子类中父类的成员变量当成整体对象，作为子类中的一个自定义类型成员看待
class Student : public Person
{
public:
	// 报错
	//Student(const char* name, int num)
	//	//:_name(name)
	//	//,_num(num)
	//{
	//	cout << "Student" << endl;
	//}

	//Person有默认构造时,不报错
	//Student(const char* name, int num)
	//	//:_name(name)
	//	//,_num(num)
	//{
	//	//_name = name;或
	//	Person(name);
	//	_num = num;
	//	cout << "Student" << endl;
	//}


	Student(const char* name, int num)
		:Person(name) //没有默认构造，显⽰调用构造函数
		,_num(num)
	{ cout << "Student" << endl; }

	Student(const Student& s)
		:Person(s)  //显示调用拷贝构造
		,_num(s._num)
	{
		// 深拷贝需要自己写，否则默认生成的就可以够了
	}

	Student& operator=(const Student& s)
	{
		// 深拷贝 需要自己写，否则默认生成的就可以够了
		if (this != &s)
		{
			Person::operator=(s); //显示调用赋值重载
			_num = s._num;
		}
		return *this;
	}

	~Student()
	{
		// 不需要显示调用，保证析构时，先子后父
		//Person::~Person();
		cout << "~Student" << endl;

		// 派生类析构结束后，自动调用父类的析构
	}
protected:
	int _num = 1; //学号
};

int main()
{
	Student s1("张三", 18);
	return 0;
}

